/*
 * Copyright 2019-2025 the original author or authors.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * https://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.iiifi.kite.security.handle;

import java.util.Optional;
import java.util.stream.Stream;

import org.springframework.util.PatternMatchUtils;

import com.iiifi.kite.core.model.KiteAccount;
import com.iiifi.kite.security.utils.KiteAccountUtils;

import lombok.extern.slf4j.Slf4j;

/**
 * 表达式函数
 *
 * @author kite@iiifi.com 花朝
 */
@Slf4j
public class KitePermissionsFun {

    /**
     * 总是返回true，表示允许所有的
     *
     * <pre>
     * &#64;KitePermissions("permitAll()")
     * </pre>
     *
     * @return true
     */
    public boolean permitAll() {
        return true;
    }

    /**
     * 总是返回false，表示所有的都不允许
     *
     * <pre>
     * &#64;KitePermissions("denyAll()")
     * </pre>
     *
     * @return true
     */
    public boolean denyAll() {
        return false;
    }

    /**
     * 已登录
     *
     * <pre>
     * &#64;KitePermissions("authenticated()")
     * </pre>
     *
     * @return 是否登录
     */
    public boolean authenticated() {
        KiteAccount account = KiteAccountUtils.getAccount();
        return account != null;
    }

    /**
     * 判断请求是否有权限
     *
     * <pre>
     * &#64;KitePermissions("hasPermission('get:user:*')")
     * </pre>
     *
     * @param permission 权限表达式
     * @return 是否有权限
     */
    public boolean hasPermission(final String permission) {
        KiteAccount account = KiteAccountUtils.getAccount();
        // 采用 PatternMatchUtils 支持表达式通配符
        return Optional.ofNullable(account)
                .map(KiteAccount::getPermissions)
                .map(x -> x.stream().anyMatch(y -> PatternMatchUtils.simpleMatch(permission, y)))
                .orElse(Boolean.FALSE);
    }

    /**
     * 判断当前用户是否有指定角色
     *
     * <pre>
     * &#64;KitePermissions("hasRole('admin')")
     * </pre>
     *
     * @param role 权限表达式
     * @return 是否有指定角色
     */
    public boolean hasRole(final String role) {
        KiteAccount account = KiteAccountUtils.getAccount();
        // 采用 PatternMatchUtils 支持表达式通配符
        return Optional.ofNullable(account)
                .map(KiteAccount::getRoles)
                .map(x -> x.stream().anyMatch(y -> PatternMatchUtils.simpleMatch(role, y.getCode())))
                .orElse(Boolean.FALSE);
    }

    /**
     * 判断按钮是否有任意角色
     *
     * <pre>
     * &#64;KitePermissions("hasAnyRole('admin', 'test')")
     * </pre>
     *
     * @param role 角色
     * @return {boolean}
     */
    public boolean hasAnyRole(final String... role) {
        KiteAccount account = KiteAccountUtils.getAccount();
        return Optional.ofNullable(account)
                .map(KiteAccount::getRoles)
                .map(x -> Stream.of(role).anyMatch(x::contains))
                .orElse(Boolean.FALSE);
    }

    /**
     * 判断用户是否当前登录用户
     *
     * <pre>
     * &#64;KitePermissions("isMe(#userVO.accountId)")
     * </pre>
     *
     * @param accountId 用户id
     * @return {boolean}
     */
    public boolean isMe(final Long accountId) {
        KiteAccount account = KiteAccountUtils.getAccount();
        return Optional.ofNullable(account)
                .map(KiteAccount::getId)
                .map(x -> x.equals(accountId))
                .orElse(Boolean.FALSE);
    }
}
